package experiment5.demo2;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;

/**
 * @author Anonymous
 * @description 发送端
 * @date 2020/3/9 10:01
 * <p>
 * 这里需要输出流
 * 输出流对象需要通过Socket获取，在当前客户端连接到服务器之后，Socket对象存在
 * 的情况下才可以启动的
 * 成员变量：
 * 输出流
 * DataOutputStream
 * 需要一个从键盘上输入数据使用的输入流，获取用户输入信息
 * BufferedReader
 * 标记是否连接
 * 构造方法：
 * 需要Socket作为当前构造的参数，第一次访问服务器需要带有用户名，用于注册
 * 成员方法：
 * 发送数据给服务器
 * 从键盘上获取用户的数据
 */
public class ClientSend implements Runnable {

    /**
     * 基于Socket获取的输出流对象，用于发送数据给服务器
     */
    private DataOutputStream outputStream;

    /**
     * 从键盘上获取用户输入的BufferedReader字符缓冲输入流
     */
    private BufferedReader console;

    /**
     * 是否连接
     */
    private boolean connection;

    /**
     * 使用客户端和服务器连接使用的Socket对象，和用户指定的用户名创建
     * ClientSend线程对象，同时初始化输出流和键盘录入输入流对象
     *
     * @param socket   客户端连接服务器对应的Socket对象
     * @param userName 用户指定的用户名，用于服务器注册
     */
    public ClientSend(Socket socket, String userName) {
        // 初始化输出流和输出流
        try {
            outputStream = new DataOutputStream(socket.getOutputStream());
            console = new BufferedReader(new InputStreamReader(System.in));

            // 发送用户名给服务器注册 需要完成一个send方法
            send(userName);
            connection = true;
        } catch (IOException e) {
            e.printStackTrace();
            // 连接标记关闭，同时处理对应的输入流和键盘录入流
            connection = false;
            CloseUtil.closeAll(outputStream, console);
        }

    }

    /**
     * 从键盘上获取用户输入的数据
     *
     * @return 用户输入的数据字符串形式
     */
    public String getMsgFromConsole() {
        String msg = null;

        try {
            // 从键盘上读取一行数据
            msg = console.readLine();
        } catch (IOException e) {
            e.printStackTrace();
            /*
            发生异常：
                1. connection连接标记改成false
                2. 不是null需要关闭资源
                    outputStream, console
             */
            connection = false;
            CloseUtil.closeAll(outputStream, console);
        }

        return msg;
    }

    /**
     * 发送数据给服务器
     *
     * @param msg 需要发送给服务器的数据
     */
    public void send(String msg) {
        // 如果这里数据为null,或者"" 不发送
        try {
            if (msg != null && !"".equals(msg)) {

                outputStream.writeUTF(msg);
                outputStream.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
            /*
            发生异常：
                1. connection连接标记改成false
                2. 不是null需要关闭资源
                    outputStream, console
             */
            connection = false;
            CloseUtil.closeAll(outputStream, console);
        }
    }

    /**
     * 线程代码，只要当前connection是连接状态，一直执行send和getMsgFromConsole
     */
    @Override
    public void run() {
        while (connection) {
            send(getMsgFromConsole());
        }
    }
}
